package com.bnzj.core.persistence.query;

import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import lombok.Getter;

/**
 * 比较表达式类，参考org.hibernate.query.criteria.internal.predicate.AbstractSimplePredicate设计
 * 
 * @author barry
 * @date 2019-09-29
 * @see org.hibernate.query.criteria.internal.predicate.AbstractSimplePredicate
 */
@Getter
public class CompareExpression extends AbstractExpression {

    private final String field;// 表字段名称

    private final String aliasField;// 同一个field有多个条件的时候，就需要该参数区分

    private final Object value;// 比较的值

    private final Object value2;// 第二个比较的值(between专用)

    private final CompareType compareType;// 比较类型

    public static IExpression build(String field, CompareType compareType, Object value) {
        return new CompareExpression(field, compareType, value);
    }
    public static IExpression build(String field, CompareType compareType, String aliasField, Object value) {
        return new CompareExpression(field, compareType, aliasField, value);
    }
    public static IExpression build(String field, CompareType compareType, String aliasField, Object value, Object value2) {
        return new CompareExpression(field, compareType, aliasField, value, value2);
    }

    protected CompareExpression(String field, CompareType compareType, Object value) {
        this(field, compareType, null, value);
    }

    protected CompareExpression(String field, CompareType compareType, String aliasField, Object value) {
        this(field, compareType, aliasField, value, null);
    }

    protected CompareExpression(String field, CompareType compareType, String aliasField, Object value, Object value2) {
        super(compareType.isNegated());
        this.field = field;
        this.compareType = compareType;
        this.value = value;
        this.aliasField = aliasField;
        this.value2 = value2;
    }

    /* (non-Javadoc)
     * @see com.bnzj.core.persistence.query.SimpleExpression#buildSQL()
     */
    @Override
    public String buildSQL(Map<String, Object> paramsMap) {
        if (value == null || (value instanceof String && StringUtils.isEmpty((String) value))) {
            return "";//为空就忽略该条件 1=1
        }
        Object value = this.value;
        String aliasField = this.aliasField;
        StringBuilder sql = new StringBuilder("(");
        CompareOperator compareOperator = compareType.getCompareOperator();
        if(CompareOperator.expression == compareOperator) {
            sql.append(value).append(")");
            return sql.toString();
        } else 
        if (CompareOperator.startsWith == compareOperator) {
            value = value + "%";
        } else 
        if (CompareOperator.endWith == compareOperator) {
            value = "%" + value;
        } else 
        if (CompareOperator.like == compareOperator) {
            value = "%" + value + "%";
        }
        if(StringUtils.isEmpty(aliasField)){
            aliasField = field;
        }
        if (compareOperator == CompareOperator.between) {
            sql.append(field + " " + compareType.getKeyword() + " :" + aliasField + "1 and :" + aliasField + "2");
            paramsMap.put(aliasField + "1", value);
            paramsMap.put(aliasField + "2", value2);
        } else {
            sql.append(field + " " + compareType.getKeyword() + " :" + aliasField);
            paramsMap.put(aliasField, value);
        }
        return sql.append(")").toString();
    }

    @Override
    public IExpression not() {
        return CompareExpression.build(field, compareType.getNegatedCompareType(), aliasField, value, value2);
    }
}
